class_name BallState
extends Node

signal state_transition_requested(state: Ball.State)

const GRAVITY := 10.0

var ball: Ball
var ball_sprite: Sprite2D
var player_detection_area: Area2D
var carried: Player
var animation_player: AnimationPlayer
var state_data: BallStateData
var shoot_particles: GPUParticles2D

func setup(context_ball: Ball, context_state_data: BallStateData,context_player_detection_area: Area2D, context_carried: Player, context_animation_player: AnimationPlayer, context_ball_sprite: Sprite2D, context_shoot_particles: GPUParticles2D) -> void:
	ball = context_ball
	player_detection_area = context_player_detection_area
	carried = context_carried
	animation_player = context_animation_player
	ball_sprite = context_ball_sprite
	state_data = context_state_data
	shoot_particles = context_shoot_particles
	
func state_register(call_func: Callable) -> void:
	state_transition_requested.connect(call_func)
	
func state_transition(state: Ball.State, data: BallStateData = BallStateData.new()) -> void:
	state_transition_requested.emit(state, data)
	
	
func set_ball_animation_from_velocity() -> void:
	if ball.velocity == Vector2.ZERO:
		animation_player.play("idle")
	elif ball.velocity.x > 0:
		animation_player.play("roll")
		animation_player.advance(0)
	elif  ball.velocity.x < 0:
		animation_player.play_backwards("roll")
		animation_player.advance(0)
		
func process_gravity(delta: float, bounciness: float = 0.0) -> void:
	if ball.height > 0 or ball.height_velocity > 0:
		ball.height_velocity -= GRAVITY * delta
		ball.height += ball.height_velocity
		if ball.height < 0:
			ball.height = 0
			if bounciness > 0 and ball.height_velocity < 0:
				ball.height_velocity = -ball.height_velocity * bounciness
				ball.velocity *= bounciness
				
func move_and_bouness(delta: float) -> void:
		var collider := ball.move_and_collide(ball.velocity * delta)
		if collider != null:
			ball.velocity = ball.velocity.bounce(collider.get_normal()) * ball.BOUNCINESS
			SoundPlayer.play(SoundPlayer.Sound.BOUNCE)
			ball.switch_state(Ball.State.FREEFORM)
			
func can_air_interact() -> bool:
	return false
			
			
